/**
 * HTTP 请求工具
 * 基于 Fetch API 封装，提供拦截器和错误处理
 */

import { message as antMessage } from 'ant-design-vue'
import type { ApiResponse } from '@/types'
import { storage, StorageKey } from './storage'

interface RequestConfig extends RequestInit {
  url: string
  params?: Record<string, any>
  data?: any
  timeout?: number
  showError?: boolean
}

interface RequestInterceptor {
  onFulfilled?: (config: RequestConfig) => RequestConfig | Promise<RequestConfig>
  onRejected?: (error: any) => any
}

interface ResponseInterceptor {
  onFulfilled?: (response: Response) => Response | Promise<Response>
  onRejected?: (error: any) => any
}

class HttpClient {
  private baseURL: string = ''
  private timeout: number = 10000
  private requestInterceptors: RequestInterceptor[] = []
  private responseInterceptors: ResponseInterceptor[] = []

  constructor(baseURL?: string) {
    if (baseURL) {
      this.baseURL = baseURL
    }
  }

  /**
   * 添加请求拦截器
   */
  addRequestInterceptor(interceptor: RequestInterceptor) {
    this.requestInterceptors.push(interceptor)
  }

  /**
   * 添加响应拦截器
   */
  addResponseInterceptor(interceptor: ResponseInterceptor) {
    this.responseInterceptors.push(interceptor)
  }

  /**
   * 构建完整 URL
   */
  private buildURL(url: string, params?: Record<string, any>): string {
    const fullURL = url.startsWith('http') ? url : this.baseURL + url

    if (!params) return fullURL

    const queryString = Object.keys(params)
      .filter(key => params[key] !== undefined && params[key] !== null)
      .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
      .join('&')

    return queryString ? `${fullURL}?${queryString}` : fullURL
  }

  /**
   * 处理请求配置
   */
  private async processRequestConfig(config: RequestConfig): Promise<RequestConfig> {
    let processedConfig = { ...config }

    // 执行请求拦截器
    for (const interceptor of this.requestInterceptors) {
      if (interceptor.onFulfilled) {
        processedConfig = await interceptor.onFulfilled(processedConfig)
      }
    }

    return processedConfig
  }

  /**
   * 处理响应
   */
  private async processResponse(response: Response): Promise<Response> {
    let processedResponse = response

    // 执行响应拦截器
    for (const interceptor of this.responseInterceptors) {
      if (interceptor.onFulfilled) {
        processedResponse = await interceptor.onFulfilled(processedResponse)
      }
    }

    return processedResponse
  }

  /**
   * 发起请求
   */
  async request<T = any>(config: RequestConfig): Promise<ApiResponse<T>> {
    try {
      // 处理请求配置
      const processedConfig = await this.processRequestConfig(config)

      // 构建 URL
      const url = this.buildURL(processedConfig.url, processedConfig.params)

      // 设置默认请求头
      const headers = new Headers(processedConfig.headers)
      if (!headers.has('Content-Type')) {
        headers.set('Content-Type', 'application/json')
      }

      // 添加 Token
      const token = storage.get<string>(StorageKey.TOKEN)
      if (token) {
        headers.set('Authorization', `Bearer ${token}`)
      }

      // 处理请求体
      let body = processedConfig.data
      if (body && typeof body === 'object') {
        body = JSON.stringify(body)
      }

      // 发起请求（带超时控制）
      const controller = new AbortController()
      const timeoutId = setTimeout(
        () => controller.abort(),
        processedConfig.timeout || this.timeout
      )

      const response = await fetch(url, {
        ...processedConfig,
        headers,
        body,
        signal: controller.signal,
      })

      clearTimeout(timeoutId)

      // 处理响应
      const processedResponse = await this.processResponse(response)

      // 解析响应数据
      const data = await processedResponse.json()

      // 检查响应状态
      if (!processedResponse.ok) {
        throw new Error(data.message || '请求失败')
      }

      return data
    } catch (error: any) {
      // 错误处理
      const showError = config.showError !== false
      const errorMessage = error.message || '网络请求失败'

      if (showError) {
        antMessage.error(errorMessage)
      }

      throw error
    }
  }

  /**
   * GET 请求
   */
  get<T = any>(url: string, params?: Record<string, any>, config?: Omit<RequestConfig, 'url' | 'params' | 'method'>): Promise<ApiResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      params,
      method: 'GET',
    })
  }

  /**
   * POST 请求
   */
  post<T = any>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'data' | 'method'>): Promise<ApiResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      data,
      method: 'POST',
    })
  }

  /**
   * PUT 请求
   */
  put<T = any>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'data' | 'method'>): Promise<ApiResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      data,
      method: 'PUT',
    })
  }

  /**
   * DELETE 请求
   */
  delete<T = any>(url: string, params?: Record<string, any>, config?: Omit<RequestConfig, 'url' | 'params' | 'method'>): Promise<ApiResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      params,
      method: 'DELETE',
    })
  }
}

// 创建默认实例
export const http = new HttpClient()

// 添加默认请求拦截器
http.addRequestInterceptor({
  onFulfilled: (config) => {
    // 可以在这里添加全局请求处理逻辑
    return config
  },
})

// 添加默认响应拦截器
http.addResponseInterceptor({
  onFulfilled: (response) => {
    // 可以在这里添加全局响应处理逻辑
    return response
  },
  onRejected: (error) => {
    // 全局错误处理
    if (error.name === 'AbortError') {
      console.error('Request timeout')
    }
    return Promise.reject(error)
  },
})

export default http
